home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 23 / AACD 23.iso / AACD / Programming / tek / visual / createvisual.c < prev    next >
C/C++ Source or Header  |  2001-05-12  |  9KB  |  420 lines

  1.  
  2. #include "tek/visual.h"
  3. #include "tek/debug.h"
  4. #include "tek/kn/visual.h"
  5.  
  6. /* 
  7. **    TEKlib
  8. **    (C) 2001 TEK neoscientists
  9. **    all rights reserved.
  10. **
  11. **    TVISUAL *TCreateVisual(TAPTR task, TTAGITEM *tags)
  12. **
  13. **    create visual object.
  14. **
  15. **    tags
  16. **        TTask_MMU, user mmu
  17. **
  18. */
  19.  
  20.  
  21. static TINT destroyvisual(TVISUAL *visual);
  22. static TBOOL initvisualtask(TAPTR task);
  23. static TVOID visualtask(TAPTR task);
  24.  
  25. TVISUAL *TCreateVisual(TAPTR task, TTAGITEM *tags)
  26. {
  27.     if (task)
  28.     {
  29.         TAPTR mmu = TGetTagValue(TTask_MMU, &((TTASK *) task)->heapmmu, tags);
  30.         TVISUAL *visual = TMMUAllocHandle(mmu, (TDESTROYFUNC) destroyvisual, sizeof(TVISUAL));
  31.         if (visual)
  32.         {
  33.             visual->asyncport = TCreatePort(task, TNULL);
  34.             visual->iport = TCreatePort(task, TNULL);
  35.             
  36.             visual->prefwidth = (TINT) TGetTagValue(TVisual_PixWidth, (TTAG) -1, tags);
  37.             visual->prefheight = (TINT) TGetTagValue(TVisual_PixHeight, (TTAG) -1, tags);
  38.             visual->preftitle = (TSTRPTR) TGetTagValue(TVisual_Title, (TTAG) TNULL, tags);
  39.  
  40.             if (visual->asyncport && visual->iport)
  41.             {
  42.                 TINT i;
  43.                 TAPTR msg;
  44.                 TBOOL success = TTRUE;
  45.                 
  46.                 for (i = 0; i < TVISUAL_NUMDRMSG && success; ++i)
  47.                 {
  48.                     msg = TTaskAllocMsg(task, sizeof(TDRAWMSG));
  49.                     if (msg)
  50.                     {
  51.                         TAddTail(&visual->asyncport->msglist, (TNODE *)(((TMSG *) msg) - 1));
  52.                     }
  53.                     else
  54.                     {
  55.                         success = TFALSE;
  56.                         break;
  57.                     }
  58.                 }
  59.  
  60.                 if (success)
  61.                 {
  62.                     if (kn_initlock(&visual->lock))
  63.                     {
  64.                         TTAGITEM tasktags[3];
  65.                         tasktags[0].tag = TTask_UserData;
  66.                         tasktags[0].value = (TTAG) visual;
  67.                         tasktags[1].tag = TTask_InitFunc;
  68.                         tasktags[1].value = (TTAG) initvisualtask;
  69.                         tasktags[2].tag = TTAG_DONE;
  70.                         
  71.                         visual->task = TCreateTask(task, (TTASKFUNC) visualtask, tasktags);
  72.                         if (visual->task)
  73.                         {
  74.                             visual->parenttask = task;
  75.                             visual->refcount = 0;
  76.                             visual->main = TTRUE;
  77.                             return visual;
  78.                         }
  79.                         
  80.                         kn_destroylock(&visual->lock);
  81.                     }
  82.                 }
  83.                 
  84.                 while ((msg = TRemHead(&visual->asyncport->msglist)))
  85.                 {
  86.                     TFreeMsg(((TMSG *) msg) + 1);
  87.                 }
  88.             }
  89.             
  90.             TDestroy(visual->iport);
  91.             TDestroy(visual->asyncport);
  92.             TMMUFreeHandle(visual);
  93.         }
  94.     }
  95.  
  96.     return TNULL;
  97. }
  98.  
  99.  
  100.  
  101. static TBOOL initvisualtask(TAPTR task)
  102. {
  103.     TVISUAL *visual = TTaskGetData(task);
  104.  
  105.     visual->ireplyport = TCreatePort(task, TNULL);
  106.     if (visual->ireplyport)
  107.     {
  108.         TINT i;
  109.         TAPTR msg;
  110.         TBOOL success = TTRUE;
  111.  
  112.         for (i = 0; i < TVISUAL_NUMIMSG && success; ++i)
  113.         {
  114.             msg = TTaskAllocMsg(task, sizeof(TIMSG));
  115.             if (msg)
  116.             {
  117.                 TAddTail(&visual->ireplyport->msglist, (TNODE *) (((TMSG *) msg) - 1));
  118.             }
  119.             else
  120.             {
  121.                 success = TFALSE;
  122.                 break;
  123.             }
  124.         }
  125.  
  126.         if (success)
  127.         {        
  128.             visual->knvisual = kn_createvisual(&((TTASK *) task)->heapmmu, visual->preftitle, visual->prefwidth, visual->prefheight);    
  129.             if (visual->knvisual)
  130.             {
  131.                 return TTRUE;
  132.             }
  133.         }
  134.  
  135.         TDestroy(visual->ireplyport);
  136.     }
  137.     
  138.     return TFALSE;
  139. }
  140.  
  141.  
  142.  
  143. static TVOID visualtask(TAPTR task)
  144. {
  145.     TUINT signals = 0;
  146.     TBOOL visualevent = TFALSE;
  147.     TVISUAL *visual = TTaskGetData(task);
  148.     TPORT *drawport = TTaskPort(task);
  149.     TPORT *ireplyport = visual->ireplyport;
  150.     TMSG *rawmsg;
  151.     TDRAWMSG *drawmsg;
  152.     TINT numprocessed;
  153.  
  154.     TUINT eventmask = TITYPE_VISUAL_CLOSE;            /* initial event mask */
  155.  
  156.     kn_setinputmask(visual->knvisual, eventmask);
  157.  
  158.  
  159.     do
  160.     {
  161.         visualevent = kn_waitvisual(visual->knvisual, &((TTASK *) task)->timer, &((TTASK *) task)->sigevent);
  162.         signals = TSetSignal(task, 0, drawport->signal | TTASK_SIG_ABORT);
  163.         if (visualevent) dbvprintf(1,"TEKLIB visualtask: event\n");
  164.  
  165.         /* 
  166.         **    generate input messages
  167.         */
  168.  
  169.         if (visualevent)
  170.         {
  171.             kn_lock(&ireplyport->lock);
  172.             
  173.             for (;;)
  174.             {
  175.                 rawmsg = (TMSG *) TRemHead(&ireplyport->msglist);
  176.                 if (rawmsg)
  177.                 {
  178.                     if (kn_getnextinput(visual->knvisual, (TIMSG *) (rawmsg + 1), eventmask))
  179.                     {
  180.                         TPutReplyMsg(visual->iport, ireplyport, rawmsg + 1);
  181.                         continue;
  182.                     }
  183.                     else
  184.                     {
  185.                         TAddHead(&ireplyport->msglist, (TNODE *) rawmsg);
  186.                     }
  187.                 }
  188.                 break;
  189.             }
  190.     
  191.             kn_unlock(&ireplyport->lock);
  192.         }
  193.  
  194.  
  195.         /* 
  196.         **    process draw messages
  197.         */
  198.  
  199.         if (signals & drawport->signal)
  200.         {
  201.             numprocessed = 0;
  202.     
  203.             while ((drawmsg = TGetMsg(drawport)))
  204.             {
  205.                 switch (drawmsg->jobcode)
  206.                 {
  207.                     case TVJOB_ALLOCPEN:
  208.                         drawmsg->op.rgbpen.pen = kn_allocpen(visual->knvisual, drawmsg->op.rgbpen.rgb);
  209.                         TReplyMsg(drawmsg);
  210.                         break;
  211.     
  212.                     case TVJOB_FREEPEN:
  213.                         kn_freepen(visual->knvisual, drawmsg->op.pen.pen);
  214.                         TAckMsg(drawmsg);
  215.                         break;
  216.     
  217.                     case TVJOB_RECT:
  218.                         kn_setfgpen(visual->knvisual, drawmsg->op.colrect.pen);
  219.                         kn_rect(visual->knvisual, 
  220.                             drawmsg->op.colrect.x, drawmsg->op.colrect.y,
  221.                             drawmsg->op.colrect.w, drawmsg->op.colrect.h);
  222.                         TAckMsg(drawmsg);
  223.                         break;
  224.     
  225.                     case TVJOB_FRECT:
  226.                         kn_setfgpen(visual->knvisual, drawmsg->op.colrect.pen);
  227.                         kn_frect(visual->knvisual, 
  228.                             drawmsg->op.colrect.x, drawmsg->op.colrect.y,
  229.                             drawmsg->op.colrect.w, drawmsg->op.colrect.h);
  230.                         TAckMsg(drawmsg);
  231.                         break;
  232.     
  233.                     case TVJOB_LINE:
  234.                         kn_setfgpen(visual->knvisual, drawmsg->op.colrect.pen);
  235.                         kn_line(visual->knvisual,
  236.                             drawmsg->op.colrect.x, drawmsg->op.colrect.y,
  237.                             drawmsg->op.colrect.w, drawmsg->op.colrect.h);
  238.                         TAckMsg(drawmsg);
  239.                         break;
  240.     
  241.                     case TVJOB_PLOT:
  242.                         kn_setfgpen(visual->knvisual, drawmsg->op.plot.pen);
  243.                         kn_plot(visual->knvisual, drawmsg->op.plot.x, drawmsg->op.plot.y);
  244.                         TAckMsg(drawmsg);
  245.                         break;
  246.     
  247.                     case TVJOB_CLEAR:
  248.                     {
  249.                         struct knvisual_parameters param;
  250.                         kn_getparameters(visual->knvisual, ¶m);
  251.                         kn_setfgpen(visual->knvisual, drawmsg->op.pen.pen);
  252.                         kn_frect(visual->knvisual, 0,0, param.pixelwidth, param.pixelheight);
  253.                         TAckMsg(drawmsg);
  254.                         break;
  255.                     }
  256.  
  257.                     case TVJOB_LINEARRAY:
  258.                     {
  259.                         TINT i, x1, y1, x2, y2, *p;
  260.                         kn_setfgpen(visual->knvisual, drawmsg->op.array.pen);
  261.                         p = drawmsg->op.array.array;
  262.                         x1 = *p++;
  263.                         y1 = *p++;
  264.                         for (i = 1; i < drawmsg->op.array.num; ++i)
  265.                         {
  266.                             x2 = *p++;
  267.                             y2 = *p++;
  268.                             kn_line(visual->knvisual, x1, y1, x2, y2);
  269.                             x1 = x2;
  270.                             y1 = y2;
  271.                         }
  272.                         TAckMsg(drawmsg);
  273.                         break;
  274.                     }
  275.     
  276.                     case TVJOB_SCROLL:
  277.                         kn_scroll(visual->knvisual, 
  278.                             drawmsg->op.scroll.x, drawmsg->op.scroll.y,
  279.                             drawmsg->op.scroll.w, drawmsg->op.scroll.h,
  280.                             drawmsg->op.scroll.dx, drawmsg->op.scroll.dy);
  281.                         TAckMsg(drawmsg);
  282.                         break;
  283.     
  284.                     case TVJOB_TEXT:
  285.                         kn_setfgpen(visual->knvisual, drawmsg->op.text.fgpen);
  286.                         kn_setbgpen(visual->knvisual, drawmsg->op.text.bgpen);
  287.                         kn_drawtext(visual->knvisual, drawmsg->op.text.x, drawmsg->op.text.y,
  288.                             drawmsg->op.text.text, drawmsg->op.text.len);
  289.                         TAckMsg(drawmsg);
  290.                         break;
  291.  
  292.                     case TVJOB_FLUSHAREA:
  293.                         kn_flush(visual->knvisual, 
  294.                             drawmsg->op.rect.x, drawmsg->op.rect.y,
  295.                             drawmsg->op.rect.w, drawmsg->op.rect.h);
  296.                         TAckMsg(drawmsg);
  297.                         break;
  298.                     
  299.                     case TVJOB_FLUSH:
  300.                         kn_flush(visual->knvisual, -1, -1, -1, -1);
  301.                         TAckMsg(drawmsg);
  302.                         break;
  303.  
  304.                     case TVJOB_SYNC:
  305.                         TAckMsg(drawmsg);        /* synchronization only */
  306.                         break;
  307.  
  308.                     case TVJOB_SETINPUT:
  309.                         drawmsg->op.input.oldmask = eventmask;
  310.                         eventmask &= ~drawmsg->op.input.clearmask;
  311.                         eventmask |= drawmsg->op.input.setmask;
  312.                         if (eventmask != drawmsg->op.input.oldmask)
  313.                         {
  314.                             kn_setinputmask(visual->knvisual, eventmask);
  315.                         }
  316.                         TReplyMsg(drawmsg);
  317.                         break;
  318.     
  319.                     case TVJOB_DRAWRGB:
  320.                         kn_drawrgb(visual->knvisual, 
  321.                             drawmsg->op.rgb.rgbbuf,
  322.                             drawmsg->op.rgb.x,
  323.                             drawmsg->op.rgb.y,
  324.                             drawmsg->op.rgb.w,
  325.                             drawmsg->op.rgb.h,
  326.                             drawmsg->op.rgb.totw);
  327.                         TAckMsg(drawmsg);
  328.                         break;
  329.  
  330.                     case TVJOB_GETATTRS:
  331.                     {
  332.                         struct knvisual_parameters p;
  333.                         kn_getparameters(visual->knvisual, &p);
  334.                         drawmsg->op.attrs.pixwidth = p.pixelwidth;
  335.                         drawmsg->op.attrs.pixheight = p.pixelheight;
  336.                         drawmsg->op.attrs.textwidth = p.textwidth;
  337.                         drawmsg->op.attrs.textheight = p.textheight;
  338.                         drawmsg->op.attrs.fontwidth = p.fontwidth;
  339.                         drawmsg->op.attrs.fontheight = p.fontheight;
  340.                         TReplyMsg(drawmsg);
  341.                         break;
  342.                     }
  343.     
  344.                     default:
  345.                         tdbprintf(20, "TEKLIB visualtask: unknown drawmsg\n");
  346.                         TAckMsg(drawmsg);
  347.                 }
  348.     
  349.                 numprocessed++;
  350.                 if (numprocessed >= TVISUAL_NUMDRMSG)
  351.                 {
  352.                     break;                    /* give input events a chance */
  353.                 }
  354.             }
  355.         }
  356.  
  357.     
  358.     } while (!(signals & TTASK_SIG_ABORT));
  359.  
  360.  
  361.     {
  362.         /* not really required - task allocations will be freed automatically */
  363.     
  364.         TAPTR msg;
  365.         TUINT numfreed = 0;
  366.         while ((msg = TRemHead(&visual->ireplyport->msglist)))
  367.         {
  368.             TFreeMsg(((TMSG *) msg) + 1);
  369.             numfreed++;
  370.         }
  371.         tdbprintf1(2, "TEKLIB visualtask: freed %d imessages\n", numfreed);
  372.     }
  373.  
  374.  
  375.     kn_destroyvisual(visual->knvisual);
  376.     TDestroy(visual->ireplyport);
  377. }
  378.  
  379.  
  380.  
  381.  
  382. static TINT destroyvisual(TVISUAL *visual)
  383. {
  384.     TAPTR msg;
  385.     TBOOL done = TFALSE;
  386.     TTIME delay = {0,5000};
  387.     
  388.     for (;;)
  389.     {
  390.         kn_lock(&visual->lock);
  391.         done = (visual->refcount == 0);
  392.         kn_unlock(&visual->lock);
  393.         if (done)
  394.         {
  395.             break;
  396.         }
  397.         TTimeDelay(visual->parenttask, &delay);
  398.     }
  399.     
  400.     
  401.     kn_destroylock(&visual->lock);
  402.     
  403.  
  404.     TSignal(visual->task, TTASK_SIG_ABORT);
  405.     TDestroy(visual->task);
  406.  
  407.     while ((msg = TRemHead(&visual->asyncport->msglist)))
  408.     {
  409.         TFreeMsg(((TMSG *) msg) + 1);
  410.     }
  411.  
  412.     TDestroy(visual->iport);
  413.     /*TDestroy(visual->syncport);*/
  414.     TDestroy(visual->asyncport);
  415.  
  416.     TMMUFreeHandle(visual);
  417.     
  418.     return 0;
  419. }
  420.